package com.example.system.service.impl;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.ICaptcha;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.example.common.core.Result;
import com.example.common.core.ResultGenerator;
import com.example.common.util.TokenGenerator;
import com.example.system.dao.AdminDao;
import com.example.system.dao.ResourceDao;
import com.example.system.dao.RoleDao;
import com.example.system.dto.AuthorizationResult;
import com.example.system.dto.LoginParam;
import com.example.system.dto.RoleResult;
import com.example.system.model.Admin;
import com.example.system.dto.ResourceResult;
import com.example.system.service.AuthorizationService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
@Transactional
public class AuthorizationServiceImpl implements AuthorizationService {

    @Resource
    private HttpServletResponse response;
    @Resource
    private AdminDao adminDao;
    @Resource
    private RoleDao roleDao;
    @Resource
    private ResourceDao resourceDao;

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private ValueOperations valueOperations;

    private String CAPTCHA_KEY="system:captcha:";
    private String TOKEN_KEY="system:token:";
    @Override
    public void captcha(String uuid) throws IOException {
        if(StrUtil.isEmpty(uuid)){
            return;
        }
        ICaptcha captcha = CaptchaUtil.createCircleCaptcha(200, 100, 4, 20);
        String code = captcha.getCode();
        valueOperations.set(CAPTCHA_KEY+uuid,code, 60, TimeUnit.SECONDS);
        ServletOutputStream outputStream = response.getOutputStream();
        captcha.write(outputStream);
        outputStream.close();
    }

    @Override
    public Result login(LoginParam loginParam) {
        String code=(String) valueOperations.get(CAPTCHA_KEY + loginParam.getUuid());
        if(!loginParam.getCode().equalsIgnoreCase(code)){
            return ResultGenerator.genFailResult("图形验证码错误");
        }
        Admin admin = adminDao.selectByUserName(loginParam.getUsername());
        if(ObjectUtil.isNull(admin)){
            return ResultGenerator.genFailResult("账号不存在");
        }
        if(admin.getStatus()==0){
            return ResultGenerator.genFailResult("账户被禁用");
        }
        if(!admin.getPassword().equals(DigestUtils.md5DigestAsHex(loginParam.getPassword().getBytes()))){
            return ResultGenerator.genFailResult("密码不正确");
        }
        String token = null;
        try {
            token = TokenGenerator.generateValue();
        } catch (NoSuchAlgorithmException e) {
            return ResultGenerator.genFailResult("生成Token失败");
        }
        valueOperations.set(TOKEN_KEY+token,admin.getId().toString(),3600,TimeUnit.SECONDS);
        return ResultGenerator.genSuccessResult(token);
    }

    @Override
    public Result authorization(String token) {
        String id=(String) valueOperations.get(TOKEN_KEY+token);
        if(StrUtil.isEmpty(id)){
            return  ResultGenerator.genFailResult("未登录");
        }

        Admin admin = adminDao.selectByPrimaryKey(Integer.valueOf(id));
        if(ObjectUtil.isNull(admin)){
            return ResultGenerator.genFailResult("管理员不存在");
        }
        AuthorizationResult authorizationResult = BeanUtil.copyProperties(admin, AuthorizationResult.class);

        List<RoleResult> roleResultList = roleDao.selectRolesByAdminId(authorizationResult.getId());
        List<RoleResult> roleResults = roleResultList.stream().filter(roleResult -> roleResult.getStatus() == 1).collect(Collectors.toList());
        authorizationResult.setRoleResults(roleResults);

        List<ResourceResult> resourceResultList = resourceDao.selectResourcesByAdminId(authorizationResult.getId());
        List<ResourceResult> resourceResults = resourceResultList.stream().filter(resourceResult -> resourceResult.getStatus() == 1).collect(Collectors.toList());
        authorizationResult.setResourceResults(resourceResults);

        return ResultGenerator.genSuccessResult(authorizationResult);
    }

    @Override
    public Result logout(String token) {
        redisTemplate.delete(TOKEN_KEY+token);
        return ResultGenerator.genSuccessResult();
    }


}
